package com.beyond.core.common;

import java.io.ByteArrayOutputStream;
import java.io.IOException;

import lombok.extern.slf4j.Slf4j;

/**
 * 通讯消息转义工具
 * 描述：
 *
 * @author wangyingda
 * @date 2021年7月8日
 */
@Slf4j
public class EscapeTool {

    /**
     * 转义规则如下：
     * 0x7e ----> 0x7d + 0x5e
     * 0x7d ----> 0x7d + 0x5d
     * <p>
     * 按照指定标识符和转义字符进行转义的处理方法
     *
     * @param data 转义前的消息数据
     * @return 转义处理后的消息数据
     */

    public static byte[] escapeData(byte[] data) {
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        byte[] escapedData;
        for (int i = 0; i < data.length; i++) {
            if (data[i] == 0x7e) {
                bos.write(0x7d);
                bos.write(0x5e);
            } else if (data[i] == 0x7d) {
                bos.write(0x7d);
                bos.write(0x5d);
            } else {
                bos.write(data[i]);
            }
        }
        escapedData = bos.toByteArray();
        try {
            bos.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return escapedData;
    }

    /**
     * 转义规则如下：
     * 0x7e <---- 0x7d + 0x5e
     * 0x7d <---- 0x7d + 0x5d
     * <p>
     * 按照协议定义的标识符和转义符恢复为转义之前的消息数据的处理方法
     *
     * @param data 转义后的消息数据
     * @return 转义之前的消息数据
     */

    public static byte[] reverseEscapeData(byte[] data) {
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        byte[] restoreEscapeData;
        for (int i = 0; i < (data.length - 1); i++) {
            if (data[i] == 0x7d && data[i + 1] == 0x5e) {
                bos.write(0x7e);
                i++; //跳过0x5e字符
            } else if (data[i] == 0x7d && data[i + 1] == 0x5d) {
                bos.write(0x7d);
                i++;//跳过0x5d字符
            } else {
                bos.write(data[i]);
            }
        }

        for (int i = 0; i < (data.length - 1); i++) {
            if (data[i] == 0x7d && data[i + 1] == 0x02) {
                bos.write((byte) 0x7e);
                i++;
            } else if (data[i] == 0x7d && data[i + 1] == 0x01) {
                bos.write((byte) 0x7d);
                i++;
            } else {
                bos.write((byte) data[i]);
            }
        }

        if (data[data.length - 1] != 0x7d) { //如果最后一位是转义字符，数据是错误的
            bos.write(data[data.length - 1]);
        } else {
            log.error("数据字符错误");
        }

        restoreEscapeData = bos.toByteArray();
        try {
            bos.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return restoreEscapeData;

    }
}
